package com.everwin.web.utils;

import org.apache.commons.fileupload.FileItem;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;

public class MogoDigest {
  public static void main(String...args) throws NoSuchAlgorithmException,IOException{
    File file=new File("/Users/huzm/Temp/CentOS7.docx");
    System.out.println(digestBase64(file,"SHA-256"));
    System.out.println(digestHex(file,"SHA-256"));
    System.out.println(digestBase64(file,"SHA1"));
    System.out.println(digestHex(file,"SHA1"));
    System.out.println(digestBase64(file,"MD5"));
    System.out.println(digestHex(file,"MD5"));
  }

  public static String encode(byte[] src){
    Encoder encoder=Base64.getUrlEncoder();
    return encoder.encodeToString(src);
  }

  public static byte[] decode(String base64URL){
    Decoder decoder=Base64.getUrlDecoder();
    return decoder.decode(base64URL);
  }

  public static StringBuilder toHex(byte[] src){
    StringBuilder sb=new StringBuilder();
    for(int i=0;i<src.length;i++){
      int b=src[i]&0xFF;
      if(b<0x10) sb.append('0');
      String s=Integer.toHexString(b);
      sb.append(s);
    }
    return sb;
  }

  public static byte[] fromHex(String hex){
    int slen=hex.length();
    int blen=(slen+1)/2;
    int lessZero=blen*2-slen;
    byte[] result=new byte[blen];
    for(int i=0;i<result.length;i++){
      int i1=i*2-lessZero;
      int i2=i*2-lessZero+1;
      char c1=i1==-1?'0':hex.charAt(i1);
      char c2=hex.charAt(i2);
      int v=Integer.parseInt(c1+""+c2,16);
      result[i]=(byte)v;
    }
    return result;
  }

  public static byte[] digest(FileItem item, String algorithm) throws NoSuchAlgorithmException,IOException{
    InputStream is=item.getInputStream();
    return digest(is,algorithm);
  }

  public static byte[] digest(InputStream is,String algorithm) throws NoSuchAlgorithmException,IOException{
    //返回实现指定摘要算法的 MessageDigest 对象。algorithm - 所请求算法的名称
    MessageDigest md=MessageDigest.getInstance(algorithm);
    //使用指定的字节数组对摘要进行最后更新，然后完成摘要计算。
    byte[] buffer=new byte[1024];
    int len;
    while((len=is.read(buffer))>0)
      md.update(buffer,0,len);  //使用指定的字节数组，从指定的偏移量开始更新摘要。
    byte[] digest=md.digest();  //通过执行诸如填充之类的最终操作完成哈希计算。在调用此方法之后，摘要被重置。
    return digest;
  }

  public static byte[] digest(File file,String algorithm) throws NoSuchAlgorithmException,IOException{
    FileInputStream fis=new FileInputStream(file);
    byte[] digest=digest(fis,algorithm);
    fis.close();
    return digest;
  }

  public static String digestHex(File file,String algorithm) throws NoSuchAlgorithmException,IOException{
    byte[] digest=digest(file,algorithm);
    StringBuilder sb=toHex(digest);
    return sb.toString();
  }

  public static String digestBase64(File file,String algorithm) throws NoSuchAlgorithmException,IOException{
    byte[] digest=digest(file,algorithm);
    String s=encode(digest);
    return s;
  }
}
